package org.nViron.nvOrganic;

//~--- non-JDK imports --------------------------------------------------------

import org.nViron.nvData.nvDataEntity;
import org.nViron.nvOrganism.nvStateMgr;
import org.nViron.nvParams.nvContextParamMgr.CONTEXTPARAM;
import org.nViron.nvParams.nvVizParamMgr.VIZPARAM;
import org.nViron.nvRender.nvRenderer;

/**
 * A Stem is the joint between a kinetic (node or root) and another node
 * @author Roland Haring <p>
 * <script type="text/javascript" src="http://www.ohloh.net/p/376434/widgets/project_basic_stats.js"></script>
 */
public class nvStem extends nvJoint {
    private VIZPARAM ripenParam = VIZPARAM.INVALID;
    private final nvNode   node;
    private float    ripenMax;
    private float    ripenMin;

    public nvStem(nvOrganic organic, nvKinetic parent) {
        super(organic, parent);

        // TODO find out why this typecast here is needed (looks like runtime thinks this is a nvTissue otherwise!)
        node = new nvNode(organic, this);
        // make the stem a bit shorter
        //node.setC1(getOrganismMgr().getSimulator().getProjection().geoToVizApprox((float)(10.0 + Math.random() * 5.0)));
        setDestination(node);
    }

    @Override
    public void addEntity(nvDataEntity entity) {
        node.addEntity(entity);
    }

    public boolean canRipen(nvDataEntity entity) {
        return (ripenParam != VIZPARAM.INVALID) && (entity.getVizValue(ripenParam) >= ripenMin)
               && (entity.getVizValue(ripenParam) <= ripenMax);
    }

    @Override
    public void degenerate() {
        node.degenerate();
    }

    public nvNode getNode() {
        return node;
    }

    @Override
    public int getNumEntities() {
        return node.getNumEntities();
    }

    public float getSimilarityTo(nvDataEntity entity) {
        return node.getSimilarityTo(entity);
    }

    public float getSimilarityTo(nvDataEntity other, CONTEXTPARAM contextParam) {
        return node.getSimilarityTo(other, contextParam);
    }

    public float getSimilarityTo(nvDataEntity other, VIZPARAM vizParam) {
        return node.getSimilarityTo(other, vizParam);
    }

    @Override
    public float getVizValue(VIZPARAM param) {
        return node.getVizValue(param);
    }

    @Override
    public void remove() {
        node.remove();
        super.remove();
    }

    @Override
    public boolean removeEntity(nvDataEntity entity) {
        return node.removeEntity(entity);
    }

     public void render(nvRenderer renderer) {
        if (!isRenderable()) {
            return;
        }

        renderer.renderStem(this);
        node.render(renderer);
    }

    public void setRipening(float min, float max, VIZPARAM param) {
        ripenMin   = min;
        ripenMax   = max;
        ripenParam = param;
    }

    @Override
    protected void setSelection(boolean b) {
        super.setSelection(b);
        node.setSelection(b);
    }

    @Override
    public void update(float timeStep) {
        super.update(timeStep);

        if ((node.getState() == nvStateMgr.SPAWN) && (getState() == nvStateMgr.SPROUTING)) {
            node.setState(nvStateMgr.SPROUTING);
        }

        node.update(timeStep);
        updateStateRelativeToChild(node);
    }

    @Override
    public void updateVizValue(VIZPARAM param) {
        node.updateVizValue(param);
    }
}



